home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
os20
/
util
/
ntsc4ntsc.lha
/
NTSC4NTSC.mod
< prev
Wrap
Text File
|
1992-10-11
|
16KB
|
456 lines
(* ------------------------------------------------------------------------
:Program. NTSC for NTSC
:Contents. Get 60 Hz for NTSC screens
:Author. Kai Bolay [kai]
:Address. Snail-Mail: E-Mail:
:Address. Hoffmannstraße 168 UUCP: kai@amokle.adsp.sub.org
:Address. D-7250 Leonberg 1 FIDO: 2:247/706.3
:History. v1.0 [kai] 15-Aug-91 (started written history)
:History. v1.1 [kai] 16-Aug-91 (bug fixes)
:History. v1.2 [kai] 26-Sep-91 (+ improved stdHeight-handling)
:History. v1.3 [kai] 19-Nov-91 (+ AutoScroll, force)
:History. v1.4 [kai] 14-Dec-91 (+ tried to improve, no success)
:History. v1.5 [kai] 19-Jan-92 (+ removed illegal writes)
:History. v1.6 [kai] 24-Mar-92 (+ NEWLOOK for all screens)
:History. v1.7 [kai] 10-Apr-92 (+ AutoScroll only if necessary)
:History. v1.8 [kai] 25-Jun-92 (- FreeTagItem()-Bug/v39 fix)
:History. v1.9 [kai] 12-Jul-92 (+ ModeNotAvailable() check)
:History. v2.0 [kai] 11-Aug-92 (+ Promote)
:Copyright. Freeware
:Language. Oberon
:Translator. AMIGA OBERON v2.42d
:Remark. Thanks to Peter Cherna
:Remark. Thanks to Franz Schwarz for telling me a possibility to
:Remark. remove illegal writes to the TagList and a lot more...
:Remark. NEWLOOK was inspired by Martin Berndt's TagScreens
:Usage. STDPAL/S,STDNTSC/S,USEAUTO/S,FORCENTSC/S,NEWLOOK/S,PROMOTE/S
:Usage. The first two options describe behaviour for StdHeight-
:Usage. Screens. The third says use AutoScroll instead of PAL.
:Usage. The forth always forces NTSC, the last enables the 2.0
:Usage. look for all screens.
------------------------------------------------------------------------ *)
MODULE NTSC4NTSC; (* $Debug- *)
(* $IF SmallData *) Not possible (* $END *)
(* $OvflChk- $RangeChk- $StackChk- $NilChk- $ReturnChk- $CaseChk- *)
IMPORT
e: Exec, I: Intuition, g: Graphics, u: Utility, d: Dos, y: SYSTEM
(* $IF DoIt *) ,dio: DebugIo (* $END *);
CONST
OpenScreenOfs = -198;
OpenScreenTagsOfs = -612;
(* $IF DoIt *)
Version = "$VER: NTSC4NTSC v2.0 (11-Aug-92) by Kai Bolay (Debug)\r\n";
(* $ELSE *)
Version = "$VER: NTSC4NTSC v2.0 (11-Aug-92) by Kai Bolay\r\n";
(* $END *)
Template = "STDPAL/S,STDNTSC/S,USEAUTO/S,FORCENTSC/S,NEWLOOK/S,PROMOTE/S";
STDPAL = 0;
STDNTSC = 1;
USEAUTO = 2;
FORCENTSC = 3;
NEWLOOK = 4;
PROMOTE = 5;
NumOpts = 6;
dblpalMonitorID = 0000A1000H; (* v39 *)
dblntscMonitorID = 000091000H; (* v39 *)
TYPE
TagArrayPtr = UNTRACED POINTER TO ARRAY MAX (INTEGER) OF u.TagItem;
ExtNewScreenPtr = UNTRACED POINTER TO I.ExtNewScreen;
OpenScreenProc = PROCEDURE (newScreen{8}: ExtNewScreenPtr): I.ScreenPtr;
OpenScreenTagsProc = PROCEDURE (newScreen{8}: I.NewScreenPtr;
paraTagList{9}: TagArrayPtr): I.ScreenPtr;
VAR
OldOpenScreen: OpenScreenProc;
OldOpenScreenTags: OpenScreenTagsProc;
OldNormRows: INTEGER;
OScanRect: g.Rectangle;
Opt: ARRAY NumOpts OF e.APTR;
RD: d.RDArgsPtr;
StdHeightMonitorID,PALMonitorID, NTSCMonitorID: LONGINT;
PROCEDURE NewOpenScreenTags* (newScreen{8}: I.NewScreenPtr;
paraTagList{9}: TagArrayPtr): I.ScreenPtr;
TYPE
PenArray = ARRAY 1 OF INTEGER;
CONST
Pens = PenArray (-1);
ES = I.EasyStruct (y.SIZE (I.EasyStruct), LONGSET {}, y.ADR ("NTSC4NTSC"),
y.ADR ("Which Mode should be used for the\nscreen named \"%s\"?"),
y.ADR ("NTSC|PAL"));
MaxTags = 10;
saLikeWorkbench = I.saDummy + 00027H; (* v39 *)
VAR
Base: I.IntuitionBasePtr;
TState, Tag, DisplayTag, TypeTag, ScrollTag: u.TagItemPtr;
Tags: ARRAY MaxTags OF u.TagItem;
DisplayID: LONGINT;
OScanRect: g.Rectangle;
Height: INTEGER;
Title: e.STRPTR;
DoScroll, ScrollMagic, Patch: BOOLEAN;
ListEnd: INTEGER;
tagList, argTagList: TagArrayPtr;
scrPtr: I.ScreenPtr;
PROCEDURE GetMonitorID (ID: LONGINT): LONGINT;
BEGIN
(* $IF DoIt *)
dio.WriteString ("GetMonitorID: ");
dio.WriteHex (y.VAL (LONGINT, y.VAL (LONGSET, ID) *
y.VAL (LONGSET, g.monitorIDMask)), 8); dio.WriteLn;
(* $END *)
RETURN y.VAL (LONGINT, y.VAL (LONGSET, ID) *
y.VAL (LONGSET, g.monitorIDMask));
END GetMonitorID;
PROCEDURE SetMonitorID (ID: LONGINT; Monitor: LONGINT): LONGINT;
BEGIN
(* $IF DoIt *)
dio.WriteString ("SetMonitorID: ");
dio.WriteHex (ID, 8); dio.WriteString (" -> ");
dio.WriteHex (y.VAL (LONGINT, y.VAL (LONGSET, ID) *
(- y.VAL (LONGSET, g.monitorIDMask))) + Monitor, 8); dio.WriteLn;
(* $END *)
RETURN y.VAL (LONGINT, y.VAL (LONGSET, ID) *
(- y.VAL (LONGSET, g.monitorIDMask))) + Monitor;
END SetMonitorID;
(* $SaveRegs+ Prepare to work in other tasks *)
BEGIN
Base := y.REG (14);
(* $IF DoIt *)
dio.WriteString ("\nHi Folks!\n");
(* $END *)
ListEnd := 0;
Height := I.stdScreenHeight;
ScrollMagic := TRUE; DoScroll := FALSE; Patch := TRUE;
Title := y.ADR ("");
DisplayTag := NIL; TypeTag := NIL; ScrollTag := NIL;
IF paraTagList # NIL THEN
tagList := u.CloneTagItems (paraTagList^);
IF tagList = NIL THEN
(* $IF DoIt *)
dio.WriteString ("No Mem to clone!\n");
(* $END *)
y.SETREG (14, Base);
RETURN OldOpenScreenTags (newScreen, paraTagList);
END;
ELSE
tagList := NIL;
END;
IF newScreen # NIL THEN
Height := newScreen.height;
Title := newScreen.defaultTitle;
(* knock out bad bits! *)
DisplayID := I.UIntToLong (y.VAL (INTEGER, newScreen.viewModes -
SET {g.sprites, g.genlockAudio, g.genLockVideo, g.extendedMode, g.vpHide}));
(*
IF (newScreen.type * I.screenType # I.customScreen) AND
(newScreen.type * I.screenType # SET {I.publicScreen}) THEN
(* $IF DoIt *)
dio.WriteString ("Type: "); dio.WriteHex (y.VAL (INTEGER, newScreen.type), 4);
(* $END *)
newScreen.type := newScreen.type + I.customScreen;
(* $IF DoIt *)
dio.WriteString (" -> "); dio.WriteHex (y.VAL (INTEGER, newScreen.type), 4); dio.WriteLn;
(* $END *)
END;
*)
(* $IF DoIt *)
dio.WriteString ("NewScreen gibbet:\n");
dio.WriteString ("Height: "); dio.WriteInt (Height, 4); dio.WriteLn;
dio.WriteString ("ViewModes: "); dio.WriteHex (y.VAL (INTEGER, newScreen.viewModes), 4); dio.WriteLn;
dio.WriteString ("DisplayID: "); dio.WriteHex (DisplayID, 8); dio.WriteLn;
(* $END *)
END; (* IF *)
IF tagList # NIL THEN
TState := y.ADR (tagList^[0]);
LOOP
Tag := u.NextTagItem (TState);
IF Tag = NIL THEN EXIT END;
(* $IF DoIt *)
dio.WriteString ("Tag: "); dio.WriteHex (y.VAL (LONGINT, Tag.tag), 8);
dio.WriteString (" Data: "); dio.WriteHex (y.VAL (LONGINT, Tag.data), 8); dio.WriteLn;
(* $END *)
CASE y.VAL (LONGINT, Tag.tag) OF
| I.saDisplayID: DisplayTag := Tag; DisplayID := Tag.data;
| I.saType: TypeTag := Tag;
| I.saAutoScroll: ScrollTag := Tag;
| I.saHeight: Height := SHORT (y.VAL (LONGINT, Tag.data));
| I.saTitle: Title := Tag.data;
| I.saOverscan: ScrollMagic := FALSE;
| I.saDClip: ScrollMagic := FALSE;
| saLikeWorkbench: Patch := (Tag.data # I.LTRUE);
ELSE
END;
END;
(* $IF DoIt *)
dio.WriteString ("TagList gibbet:\n");
dio.WriteString ("Height: "); dio.WriteInt (Height, 4); dio.WriteLn;
dio.WriteString ("DisplayID: "); dio.WriteHex (DisplayID, 8); dio.WriteLn;
(* $END *)
END;
(* $IF DoIt *)
dio.WriteString ("The DisplayID: "); dio.WriteHex (DisplayID, 8); dio.WriteLn;
(* $END *)
IF Patch THEN
IF Opt[FORCENTSC] # 0 THEN
DisplayID := SetMonitorID (DisplayID, g.defaultMonitorID);
END;
IF (GetMonitorID (DisplayID) = g.defaultMonitorID) AND
(I.QueryOverscan (SetMonitorID (DisplayID, NTSCMonitorID),
OScanRect, I.oScanText) # 0) THEN
(* $IF DoIt *)
dio.WriteString ("Let's patch: ");
(* $END *)
IF Height = I.stdScreenHeight THEN
(* $IF DoIt *)
dio.WriteString ("Std-Height\n");
(* $END *)
IF StdHeightMonitorID = g.defaultMonitorID THEN
IF I.EasyRequest (NIL, y.ADR (ES), NIL, Title) = 1 THEN
DisplayID := SetMonitorID (DisplayID, NTSCMonitorID);
ELSE
DisplayID := SetMonitorID (DisplayID, PALMonitorID);
END;
ELSE
DisplayID := SetMonitorID (DisplayID, StdHeightMonitorID);
END;
ELSE
IF (Height <= OScanRect.maxY - OScanRect.minY + 1) AND (Opt[STDPAL] = 0) THEN
(* $IF DoIt *)
dio.WriteString ("NTSC\n");
(* $END *)
DisplayID := SetMonitorID (DisplayID, NTSCMonitorID);
ELSE
IF (Opt[USEAUTO] = 0) THEN
(* $IF DoIt *)
dio.WriteString ("PAL\n");
(* $END *)
DisplayID := SetMonitorID (DisplayID, PALMonitorID);
ELSE
DoScroll := NOT (Height <= OScanRect.maxY - OScanRect.minY + 1);
DisplayID := SetMonitorID (DisplayID, NTSCMonitorID);
END;
END;
END;
END;
IF Opt[NEWLOOK] # 0 THEN
Tags[ListEnd].tag := I.saPens; Tags[ListEnd].data := y.ADR (Pens);
INC (ListEnd);
(*
Tags[ListEnd].tag := I.saFullPalette; Tags[ListEnd].data := I.LTRUE;
INC (ListEnd);
*)
END; (* IF *)
IF DisplayTag # NIL THEN
(* $IF DoIt *)
dio.WriteString ("ab in den DispTag!\n");
(* $END *)
DisplayTag.data := DisplayID;
ELSE
Tags[ListEnd].tag := I.saDisplayID; Tags[ListEnd].data := DisplayID;
INC (ListEnd);
END;
IF DoScroll THEN
(* $IF DoIt *)
dio.WriteString ("Schkroll!!\n");
(* $END *)
IF (TypeTag = NIL) AND (ScrollTag = NIL) THEN
Tags[ListEnd].tag := I.saAutoScroll; Tags[ListEnd].data := I.LTRUE;
INC (ListEnd);
ELSE
IF TypeTag # NIL THEN
TypeTag.data := y.VAL (LONGINT, y.VAL (LONGSET, TypeTag.data) +
LONGSET {I.autoScroll});
END;
IF ScrollTag # NIL THEN
ScrollTag.data := I.LTRUE;
END;
END;
IF ScrollMagic THEN
Tags[ListEnd].tag := I.saOverscan; Tags[ListEnd].data := I.oScanText;
INC (ListEnd);
END;
END;
(* $IF DoIt *)
ELSE
dio.WriteString ("It's a WB!\n");
(* $END *)
END;
IF ListEnd > 0 THEN
IF tagList = NIL THEN
(* $IF DoIt *)
dio.WriteString ("New Tags alone!\n");
(* $END *)
Tags[ListEnd].tag := u.done; Tags[ListEnd].data := 0;
INC (ListEnd);
ELSE
(* $IF DoIt *)
dio.WriteString ("New & old Tags!\n");
(* $END *)
Tags[ListEnd].tag := u.more; Tags[ListEnd].data := tagList;
INC (ListEnd);
END;
argTagList := y.ADR (Tags);
ELSE
(* $IF DoIt *)
dio.WriteString ("Old Tags alone!\n");
(* $END *)
argTagList := tagList;
END;
(* $IF DoIt *)
d.Delay (3*50);
(* $END *)
y.SETREG (14, Base);
scrPtr := OldOpenScreenTags (newScreen, argTagList);
IF tagList # NIL THEN
u.FreeTagItems (tagList^);
END;
y.SETREG (14, Base);
RETURN scrPtr;
END NewOpenScreenTags;
PROCEDURE NewOpenScreen* (newScreen{8}: ExtNewScreenPtr): I.ScreenPtr;
VAR
Base: I.IntuitionBasePtr;
nScrPtr: I.NewScreenPtr;
scrPtr: I.ScreenPtr;
(* $SaveRegs+ Prepare to work in other tasks *)
BEGIN
Base := y.REG (14);
(* $IF DoIt *)
dio.WriteString ("\nMäthschick (StdOpenScreen)!!!");
(* $END *)
(* Do the magic *)
IF (I.nsExtended IN newScreen.ns.type) THEN
nScrPtr := e.AllocVec (y.SIZE (I.NewScreen), LONGSET {});
IF nScrPtr = NIL THEN
y.SETREG (14, Base);
RETURN OldOpenScreen (newScreen);
END;
e.CopyMem (newScreen^, nScrPtr^, y.SIZE (I.NewScreen));
EXCL (nScrPtr.type, I.nsExtended);
y.SETREG (14, Base);
scrPtr := NewOpenScreenTags (nScrPtr,
y.VAL (TagArrayPtr, newScreen.extension));
e.FreeVec (nScrPtr);
y.SETREG (14, Base);
RETURN scrPtr;
ELSE
y.SETREG (14, Base);
RETURN NewOpenScreenTags (newScreen, NIL);
END;
END NewOpenScreen;
BEGIN
(* $IF DoIt *)
dio.OpenIo;
dio.WriteString ("Jappadappaduuu!\n");
(* $END *)
y.SETREG (0, d.Write (d.Output (), Version[6], y.SIZE (Version)-6));
(* 2.04 should be :-) *)
IF I.int.libNode.version < 37 THEN
IF d.Output () # NIL THEN
y.SETREG (0, d.Write (d.Output (), "Sorry, I need OS 2.04!\n", 23));
END;
HALT (20);
END;
Opt[STDPAL] := 0; Opt[STDNTSC] := 0; Opt[USEAUTO] := 0;
Opt[FORCENTSC] := 0; Opt[NEWLOOK] := 0; Opt[PROMOTE] := 0;
RD := d.ReadArgs (Template, Opt, NIL);
IF RD = NIL THEN
d.PrintF ("Usage: %s\n", y.ADR (Template));
HALT (20);
END; (* IF *)
IF (Opt[FORCENTSC] # 0) THEN
Opt[STDNTSC] := -1;
Opt[USEAUTO] := -1;
END;
IF (Opt[STDPAL] # 0) AND (Opt[STDNTSC] # 0) THEN
y.SETREG (0, d.PutStr ("Sorry, PAL & NTSC together is not possible!\n"));
HALT (20);
END;
IF Opt[PROMOTE] # 0 THEN
IF I.int.libNode.version < 39 THEN
y.SETREG (0, d.PutStr ("Promotion needs v39!\n"));
HALT (20);
END;
PALMonitorID := dblpalMonitorID;
NTSCMonitorID := dblntscMonitorID;
ELSE
PALMonitorID := g.palMonitorID;
NTSCMonitorID := g.ntscMonitorID;
END;
IF Opt[STDPAL] # 0 THEN StdHeightMonitorID := PALMonitorID END;
IF Opt[STDNTSC] # 0 THEN StdHeightMonitorID := NTSCMonitorID END;
(* NTSC & PAL available? *)
IF (g.FindDisplayInfo (PALMonitorID) = NIL) OR
(g.ModeNotAvailable (PALMonitorID) # 0) OR
(g.FindDisplayInfo (NTSCMonitorID) = NIL) OR
(g.ModeNotAvailable (NTSCMonitorID) # 0) THEN
y.SETREG (0, d.PutStr ("Sorry, PAL & NTSC must be available!\n"));
HALT (20);
END;
(* Patch *)
e.Forbid;
OldOpenScreen := y.VAL (OpenScreenProc,
e.SetFunction (I.int, OpenScreenOfs,
y.VAL (e.PROC, NewOpenScreen)));
OldOpenScreenTags := y.VAL (OpenScreenTagsProc,
e.SetFunction (I.int, OpenScreenTagsOfs,
y.VAL (e.PROC, NewOpenScreenTags)));
e.Permit;
(* Wait for Break *)
y.SETREG (0, e.Wait (LONGSET {d.ctrlC})); (* ... *)
(* Unpatch *)
e.Forbid;
OldOpenScreen := y.VAL (OpenScreenProc,
e.SetFunction (I.int, OpenScreenOfs,
y.VAL (e.PROC, OldOpenScreen)));
OldOpenScreenTags := y.VAL (OpenScreenTagsProc,
e.SetFunction (I.int, OpenScreenTagsOfs,
y.VAL (e.PROC, OldOpenScreenTags)));
e.Permit;
IF (y.VAL (y.ADDRESS, OldOpenScreen) # y.VAL (y.ADDRESS, NewOpenScreen) ) OR
(y.VAL (y.ADDRESS, OldOpenScreenTags) # y.VAL (y.ADDRESS, NewOpenScreenTags)) THEN
IF I.DisplayAlert (I.recoveryAlert,
"\x00\x10\x10Someone else patched too. Safety cannot be guarateed, please reboot!\o\n\x00\x10\x1A -> Reboot <- -> Hope and pray <- \o\o",
40) THEN
e.ColdReboot;
END;
END;
(* $IF DoIt *)
dio.CloseIo;
(* $END *)
CLOSE
IF RD # NIL THEN d.FreeArgs (RD); RD := NIL END;
END NTSC4NTSC.